<?	/*
	// File:	index.php
	// Purpose:	Includes, Coordinate.
	// Creation:	2001-10-29
	// Author:	Felix <webmaster@can-host.com>
	*/
// Turn off default error reporting
//error_reporting(0);
error_reporting(E_ALL & ~E_NOTICE);
ob_start();

//
// Start Page Load Counter
$start_load = doubleval(ereg_replace('^0\.([0-9]*) ([0-9]*)$','\\2.\\1',microtime()));

//
// include configuration & functions file & error handling
$tmp = "config.inc.php";
include($tmp);

if (!isset($cfg) || $cfg['httpd_mode'] != 'webcp') {
	$tmp = "functions.inc.phps";
	include($tmp);
}

load_globals();	

load_modules();
call_hook('web:cfg', $cfg);

/*//
// Shoot out NO-CACHE to proxies
send_header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
send_header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); 
send_header("Cache-Control: no-store, no-cache, must-revalidate");
send_header("Cache-Control: post-check=0, pre-check=0", false);
send_header("Pragma: no-cache");*/

// For some reason we get blank lines sometimes
ob_clean();

send_header('Content-Type: text/xml');
echo '<'.'?xml version="1.0" ?'.'>'."\n";

// 'dynamic' GLOBAL vars declared.
GLOBAL $T, $userdata;
// 
// Initialize certain general vars.
$T = '';
$userdata = '';
unset($personaldata);
unset($domaindata);
unset($resellerdata);
unset($error);
unset($notice);
//

//
// Initialize
//
// Disable register_globals to ensure security
ini_set('register_globals', '0');

// Set magic quotes runtime off (dont quote MySQL data)
set_magic_quotes_runtime(0);

// Ignore user abort, 60 seconds max allowed to a web interface script.
if ($cfg['httpd_mode'] != 'webcp') {
	ignore_user_abort();
}

//
// Setup Database Connection
@mysql_connect($cfg['dbhost'], $cfg['dbuser'], $cfg['dbpass']);
@mysql_select_db($cfg['dbname']);

// Load english for errors
include("lang/english.phps");

// errors
$failed = '';
$fail_level = 0;

// get remote IP address
$ip = get_remote_ip();

//var_dump($_REQUEST);

if(empty($_REQUEST['webcp_tag'])) {
	if(empty($_REQUEST['username']) || (empty($_REQUEST['password']) && empty($_REQUEST['md5pass']))) {
		$failed = 'login';
		$fail_level = 1;
	} else {
		list($username, $userdomain) = explode('@', load_input_vars('username'), 2);
		$password = load_input_vars('password');
		$md5pass = load_input_vars('md5pass');
		
		// Standardize Input
		$username = trim($username);
	
		if (!eregi($rx['user'], $username))
			$username = '_invalid';
			
		if (!$cfg['ssl']) {
			$salt = md5(floor(time() / 300).$ip);
			$password = trim($md5pass);
		} else {
			$password = md5(trim($password));
			$salt = '';
		}
	
		// Check for failed logins within the last 24 hrs from this IP
		$fl = mysql_query("SELECT count(id) as FailCount FROM log WHERE remote_ip = \"$ip\" AND log_msg = \"login failed\" AND time > DATE_SUB(NOW(), INTERVAL 1 DAY)");
		$fldata = mysql_fetch_array($fl);
		if ($fldata['FailCount'] < 15 && $fldata['FailCount'] > 2) {
			sleep($fldata['FailCount']);
		} elseif ($fldata['FailCount'] >= 15)  {
			$password = "";
		}
		
		// translate domain to ID
		$res = mysql_query('SELECT `id` FROM `domains` WHERE domain = "'.$userdomain.'" LIMIT 1') or print(mysql_error());
		list($domainid) = mysql_fetch_row($res);
		
		// Check user against database
		$dbp = mysql_query("SELECT type,DECODE(password,'".$cfg['key']."') AS password FROM users WHERE username='$username' AND id = '$domainid'") or print(mysql_error());
		$data = mysql_fetch_array($dbp);
		
		if (md5($data['password'].$salt) != $password) {
			unset($data);
		}
	
		// If the user is valid
		if (!empty($data)) {
			// Log it
			webcp_log(1,"",$username." ($domainid)","login successful", $ip);
	
			// If user is a demo, associate current webcp_tag (if it exists, else pass on)
			switch ($data['type']) {
				
				case 'demo':
				$dbp = mysql_query("SELECT webcp_tag FROM users WHERE username='$username' AND id = '$domainid'");
				$data2 = mysql_fetch_array($dbp);
				if (trim($data2['webcp_tag'])) {
					$webcp_tag = $data2['webcp_tag'];
					break;
				}
				default:
				
				// Generate Unique Tag & Update the db
				srand((float) microtime() * 1000000);
				do {
					$webcp_tag = md5(uniqid(rand()));
					$dbp = mysql_query("SELECT username FROM users WHERE webcp_tag='$webcp_tag'");
				} while (mysql_num_rows($dbp));
				mysql_query("UPDATE users SET webcp_tag='$webcp_tag', remote_addr='".$ip."', timeout='".(time() + 300)."' WHERE username='$username' AND id = '$domainid'");
			}
			
			/*// if 'cookiesec' is set, set cookies with ssl and sysname settings.  Else don't.
			if ($cfg['cookiesec']) {
				if (!send_cookie("webcp_tag",$webcp_tag,time()+5000000,"",$cfg['sysname'], $cfg['ssl']?1:0)) { echo 'Cookie failed.'; return; }
			} else {
				if (!send_cookie("webcp_tag",$webcp_tag,time()+5000000,"",$_SERVER['HTTP_HOST'])) { echo 'Cookie failed.'; return; }
			}*/
				echo '<response>'."\n"
					.'  <tag>'.$webcp_tag.'</tag>'."\n"
					.'</response>'."\n";
			return;		
		}
		
		// Else if User / Password not valid
		else {
			// Check if username is valid & log if appropriate (warn)
			$dbp = mysql_query("SELECT username FROM users WHERE username='$username' AND id = '$domainid'");
			if (mysql_num_rows($dbp))
				webcp_log(1,"",$username." ($domainid)","login failed",$ip);
			
			// Stay in login and display error message
			$failed = "invalid";
			$fail_level = 3;
		}
	}
} else {
	$webcp_tag = load_input_vars('webcp_tag');
	// verify session
	$dbp = mysql_query("SELECT timeout, type, remote_addr, suspend, ip_restrict, username, id FROM users WHERE webcp_tag='".$webcp_tag."'");
	$tmpdata = mysql_fetch_assoc($dbp);
	mysql_free_result($dbp);
	
	// fail if the tag is not recognized
	if (!is_array($tmpdata)) {
		$failed = "invalidtag";
		$fail_level = 1;
	}
	// fail if the ID expired (Automated Unique ID timeout for security)
	if (time() > $tmpdata['timeout'] AND $tmpdata['type'] != "demo") {
		$failed = "timeout";
		$fail_level = 1;
	}
	// fail if Remote user's IP is different than the IP recorded in DB (and not a demo user)
	if ($tmpdata['remote_addr'] != $ip AND $tmpdata['type'] != "demo") {
		$failed = "remote_addr";
		$fail_level = 3;
	}
	
	// fail if user is suspended
	if ($tmpdata['suspend'] == "true") { 
		$failed = "suspended";
		$fail_level = 3;
	}
	
	// fail if Remote user's IP is different than ip restriction (if on)
	if ($tmpdata['ip_restrict'] AND !ereg("^".$tmpdata['ip_restrict'],$ip)) {
		$failed = "ip_restrict";
		$fail_level = 3;
	}
}

if($fail_level != 0) {
	send_header('X-Error: '.$fail_level.';'.$failed);
	
	echo '<response>'."\n"
		.'  <salt>'.md5(floor(time() / 300).get_remote_ip()).'</salt>'."\n"
		.'</response>'."\n";
		
	return;
}

$userdata = $tmpdata;

//Verify access level
$action = load_input_vars('action');
list($cp, $url) = explode(':', $action, 2);

// Verify user access level and Set $cp Environment var: $personaldata, $domaindata, $resellerdata
// (contains info about the current panel viewed)
$number = load_input_vars('number');
if(empty($number)) $number = $userdata['id'];
//else echo 'NUMBER: '.$number;

$user = load_input_vars('user');
if(empty($user)) $user = $userdata['username'];
//else echo '- USER: '.$user;

switch($cp) {
	case "tools":
		break;
		
	case "server":
		if ($userdata['level'] < 2) {
		}
		else
			$failed = "access";
		break;
		
	case "reseller":
		if ($userdata['level'] < 3) {
			$personaldata = fetchdata("*","user",array($user, $number));
			$domaindata = fetchdata("*","domain",$number);
			$resellerdata = fetchdata("*","reseller",$number);

			if (substr($userdata['id'], 0, 5) != $resellerdata['id'] AND $userdata['level'] == '2') {
				$failed = "access";
				$fail_level = 3;
			}
			if (!trim($userdata)) {
				$failed = 'no_userdata';
				$fail_level = 3;
			}
		} else {
			$failed = "access";
			$fail_level = 3;
		}
		break;
		
	case "domain":
		if ($userdata['level'] < 4) {
			// fetch domain data and reseller name
			$personaldata = fetchdata("*","user",array($user, $number));
			$domaindata = fetchdata("*","domain",$number);
			$resellerdata = fetchdata("name","reseller",$domaindata['id']);
			
			if (!is_array($domaindata) || !is_array($resellerdata)
			  || $domaindata['type'] != 'domain') {
				$failed = "invalid_domain";
				$fail_level = 3;
			}
			
			// Verify user access validity.
			if ($userdata['level'] == 3) {
				if ($userdata['id'] != $domaindata['id']) {
					$failed = "access";
					$fail_level = 3;
				}
			}
			elseif ($userdata['level'] == 2) {
				if (substr($userdata['id'], 0, 5) != $domaindata['owner']) {
					$failed = "access";
					$fail_level = 3;
				}
			}
			elseif ($userdata['level'] > 2) {
				if ($domaindata['ip_restrict'] AND !ereg("^".$domaindata['ip_restrict'],$ip)) {
					$failed = "ip_restrict";
					$fail_level = 3;
				}
			}
			//break;
		} else {
			$failed = "access";
			$fail_level = 3;
		}
		break;
		
	case "personal":
		if ($userdata['level'] < 5) {
			
			// fetch user data and reseller name
			$personaldata = fetchdata("*","user",array($user, $number));
			$domaindata = fetchdata("host,domain,type","domain",$personaldata['id']);
			$resellerdata = fetchdata("name","reseller",$personaldata['id']);
			
			if (!is_array($domaindata) || !is_array($resellerdata)
			  || $domaindata['type'] != 'domain') {
				$failed = "invalid_domain";
				$fail_level = 3;
			}
			
			// Verify user access validity in cases of domain and reseller administrators.
			if ($userdata['level'] > $personaldata['level']) {
				$failed = "access";
				$fail_level = 3;
			}
			elseif ($userdata['level'] == 4) {
				if($user != $userdata['username']) {
					$failed = "access";
					$fail_level = 3;
				}
			}
			elseif ($userdata['level'] == 3) {
				if ($userdata['id'] != $personaldata['id']) {
					$failed = "access";
					$fail_level = 3;
				}
			}
			elseif ($userdata['level'] == 2) {
				if (substr($userdata['id'], 0, 5) != substr($personaldata['id'], 0, 5)) {
					$failed = "access";
					$fail_level = 3;
				}
			}
			$number = $personaldata['id'];
		} else {
			$failed = "access";
			$fail_level = 3;
		}
		break;
}

if($fail_level != 0) {
	send_header('X-Error: '.$fail_level.';'.$failed);
	
	echo '<response>'."\n"
		.'  <salt>'.md5(floor(time() / 300).get_remote_ip()).'</salt>'."\n"
		.'</response>'."\n";
	return;
}

$data = array(
	'userdata' => &$userdata,
	'personaldata' => &$personaldata,
	'domaindata' => &$domaindata,
	'resellerdata' => &$resellerdata,
	'error' => array(),
	'return' => array()
);

//Load correct module
$ret = call_hook('ext:'.$cp.':'.$url, $data);

//Build response

// Check if a module existed
if(count($ret)==0) {
	send_header('X-Error: 2;invalid_action');
	return;
}

// Error
if(count($data['error'])>0) {
	send_header('X-Error: 2;extended');
	echo '<errors>'."\n";
	foreach($data['error'] as $error) {
		echo '  <error>'.$error.'</error>'."\n";
	}
	echo '</errors>'."\n";
	//var_dump($data['error']);
	return;
}

// Data
//var_dump($data['return']);
echo '<response>'."\n";
array_walk($data['return'], 'array2xml', 1);
echo '</response>'."\n";

// THE END
return;
?>
